package Vo::ModelPropertyVo;

use strict;
use warnings;
use utf8;
use lib './src';

use Utils;

sub new {
    my ($class, %args) = @_; 

    my $self = {
        # 属性类型
        Type => undef,
        # 代码属性类型
        CodeType => undef,
        # 数据库类型
        SqlType => undef,
        # 属性名称
        Name => undef,
        # 下滑线名称
        UnderScoreName => undef,
        # 属性注释
        Comment => undef,
        # 属性默认值
        DefaultValue => undef,
        # 数据库映射配置的默认值
        TypeConfigurationDefaultValue => undef,
        # 数据库类型默认值
        SqlDefaultValue => undef,
        # 数据库类型最大长度
        SqlTypeMaxLength => undef,
        # 配置
        Config => undef,
    };

    foreach my $key (keys %args){
        $self->{$key} = $args{$key};
    }

    # 默认使用 UUID
    if(!$self->{Config}->{USE_UUID}.defined){
        $self->{Config}->{USE_UUID} = 1;
    }

    bless $self, $class;

    $self->{CodeType} = $self->Type2CodeType();
    $self->{DefaultValue} = $self->Type2DefaultValue();
    $self->{TypeConfigurationDefaultValue} = $self->Type2TypeConfigurationDefaultValue();
    $self->{SqlType} = $self->Type2SqlType();
    $self->{SqlDefaultValue} = $self->Type2SqlDefaultValue();
    $self->{SqlTypeMaxLength} = $self->Type2MaxLength();
    $self->{UnderScoreName} = Camel2UnderScore($self->{Name});


    return $self;
}

sub Type2CodeType{
    my ($self) = @_;

    my %typeMap = (
        Json => 'string',
        Text => 'string',
        string => 'string',
        string64 => 'string',
        string128 => 'string',
        string256 => 'string',
        string512 => 'string',
    );

    if(defined $typeMap{$self->{Type}}){
        return $typeMap{$self->{Type}};
    }

    return $self->{Type};

}

sub Type2DefaultValue{
    my ($self) = @_;

    if(defined $self->{DefaultValue}){
        return $self->{DefaultValue};
    }

    my %typeMap = (
        Json => 'string.Empty',
        Text => 'string.Empty',
        string => 'string.Empty',
        string64 => 'string.Empty',
        string128 => 'string.Empty',
        string256 => 'string.Empty',
        string512 => 'string.Empty',
        DateTime => 'DateTime.MinValue',
        DateTimeOffset => 'DateTimeOffset.MinValue',
        DateOnly => 'DateOnly.MinValue',
        bool => 'false',
        List => '[]',
        UpdateTime => 'new UpdateTime(DateTimeOffset.MinValue)',
        Deleted => 'new Deleted(bool)',
        RowVersion => 'new RowVersion(0)',
    );

    if($self->{Type} =~ /Type$/){
        return $self->{Type}.'.Unknown';
    }

    if($self->{Type} =~ /Status$/){
        return $self->{Type}.'.Unknown';
    }

    if($self->{Type} =~ /Platform$/){
        return $self->{Type}.'.Unknown';
    }

    if($self->{Type} =~ /Id$/){
        return 'null!';
    }

    if($self->{Type} =~ /^List<\w+>$/){
        return $typeMap{List};
    }


    if(defined $typeMap{$self->{Type}}){
        return $typeMap{$self->{Type}};
    }

    return undef;
}

sub Type2TypeConfigurationDefaultValue{
    my ($self) = @_;

    my %typeMap = (
        Json => 'string.Empty',
        Text => 'string.Empty',
        string => 'string.Empty',
        string64 => 'string.Empty',
        string128 => 'string.Empty',
        string256 => 'string.Empty',
        string512 => 'string.Empty',
        DateTime => 'DateTime.MinValue',
        DateTimeOffset => 'DateTimeOffset.MinValue',
        bool => 'false',
        UpdateTime => 'new UpdateTime(DateTimeOffset.MinValue)',
        Deleted => 'new Deleted(false)',
        RowVersion => 'new RowVersion(0)',
    );

    if($self->{Type} =~ /Type$/){
        return $self->{Type}.'.Unknown';
    }

    if($self->{Type} =~ /Status$/){
        return $self->{Type}.'.Unknown';
    }

    if($self->{Type} =~ /Platform$/){
        return $self->{Type}.'.Unknown';
    }

    if($self->{Type} =~ /Id$/){
        if($self->{Config}->{USE_UUID} != 0){
            return 'new '.$self->{Type}.'(Guid.Empty)';
        }
        else{
            return 'new '.$self->{Type}.'(0)';
        }
    }

    if(defined $typeMap{$self->{Type}}){
        return $typeMap{$self->{Type}};
    }

    return undef;
}

sub Type2SqlType {
    my ($self) = @_;

    my %typeMap = (
        Json => 'json',
        Text => 'text',
        string => 'varchar',
        string64 => 'varchar',
        string128 => 'varchar',
        string256 => 'varchar',
        string512 => 'varchar',
        long => 'bigint',
        int => 'int',
        DateTime => 'datetime',
        DateTimeOffset => 'datetime',
        UpdateTime => 'datetime',
        DateOnly => 'date',
        bool => 'tinyint',
        Type => 'int',
        Id => 'bigint',
        UUID => 'char',
        List => 'json',
        Deleted => 'tinyint',
        RowVersion => 'int',
    );

    if($self->{Type} =~ /Type/){
        return $typeMap{Type};
    }

    if($self->{Type} =~ /Status$/){
        return $typeMap{Type};
    }

    if($self->{Type} =~ /Platform$/){
        return $typeMap{Type};
    }

    if($self->{Type} =~ /Id/){
        if($self->{Config}->{USE_UUID} != 0){
            return $typeMap{UUID};
        }
        else{
            return $typeMap{Id};
        }
    }

    if($self->{Type} =~ /^List<\w+>$/){
        return $typeMap{List};
    }

    if(defined $typeMap{$self->{Type}}){
        return $typeMap{$self->{Type}};
    }

    return 'unknown';
}

sub Type2SqlDefaultValue {
    my ($self) = @_;
    my %typeMap = (
        string => "''",
        string64 => "''",
        string128 => "''",
        string256 => "''",
        string512 => "''",
        long => '0',
        int => '0',
        DateTime => 'current_timestamp',
        DateTimeOffset => 'current_timestamp',
        UpdateTime => 'current_timestamp',
        bool => '0',
        Type => '0',
        Id => '0',
        Deleted => '0',
    );

    if($self->{Type} =~ /Type/){
        return $typeMap{Type};
    }

    if($self->{Type} =~ /Status$/){
        return $typeMap{Type};
    }

    if($self->{Type} =~ /Platform$/){
        return $typeMap{Type};
    }

    if($self->{Type} =~ /Id/){
        if($self->{Config}->{USE_UUID} == 0){
            return $typeMap{Id};
        }
    }

    if(defined $typeMap{$self->{Type}}){
        return $typeMap{$self->{Type}};
    }

    return undef;
}

sub Type2MaxLength {
    my ($self) = @_;
    my %typeMap = (
        string => '64',
        string64 => '64',
        string128 => '128',
        string256 => '256',
        string512 => '512',
        UUID => '36',
    );

    if(defined $typeMap{$self->{Type}}){
        return $typeMap{$self->{Type}};
    }

    if($self->{Type} =~ /Id/){
        if($self->{Config}->{USE_UUID} != 0)
        {
            return $typeMap{UUID};
        }
    }

    return undef;
}

1;
